package com.wbk.lotterysystemlotteryservice.controller.biz;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wbk.lotterysystemlotteryservice.commons.bo.LotteryJoinBO;
import com.wbk.lotterysystemlotteryservice.commons.dto.LotteryDTO;
import com.wbk.lotterysystemlotteryservice.commons.dto.PrizeDTO;
import com.wbk.lotterysystemlotteryservice.entity.Lottery;
import com.wbk.lotterysystemlotteryservice.entity.Prize;
import com.wbk.lotterysystemlotteryservice.entity.QrCode;
import com.wbk.lotterysystemlotteryservice.entity.Record;
import com.wbk.lotterysystemlotteryservice.service.LotteryService;
import com.wbk.lotterysystemlotteryservice.service.PrizeService;
import com.wbk.lotterysystemlotteryservice.service.QrCodeService;
import com.wbk.lotterysystemlotteryservice.service.RecordService;
import com.wbk.user.feign.StoreFeign;
import com.wbk.user.feign.UserFeign;
import com.wbk.user.vo.StoreVO;
import com.wbk.user.vo.UserVO;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import result.Result;
import tools.TimeUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class LotteryInfoBiz {

    @Autowired
    LotteryService lotteryService;

    @Autowired
    PrizeService prizeService;

    @Autowired
    QrCodeService qrCodeService;

    @Autowired
    StoreFeign storeFeign;

    @Autowired
    UserFeign userFeign;

    @Autowired
    RecordService recordService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    public Result<PageInfo> lotteryList(Integer pageNum, Integer pageSize, Integer navigatePages) {
        PageHelper.startPage(pageNum, pageSize);
        List<Lottery> lotterys = lotteryService.getAll();

        List<LotteryDTO> lotteryDTOS = new ArrayList<>();
        for (Lottery lottery : lotterys) {
            LotteryDTO lotteryDTO = new LotteryDTO();
            BeanUtils.copyProperties(lottery, lotteryDTO);

            List<Prize> prizes = prizeService.getPrizeByLotteryId(lottery.getId());
            List<PrizeDTO> prizeDTOList = new ArrayList<>();
            for (Prize prize : prizes) {
                PrizeDTO prizeDTO = new PrizeDTO();
                BeanUtils.copyProperties(prize, prizeDTO);
                prizeDTOList.add(prizeDTO);
            }
            lotteryDTO.setPrizeDTOList(prizeDTOList);

            QrCode qrCode = qrCodeService.getQrCodeByLotteryId(lottery.getId());
            lotteryDTO.setQrCode(qrCode.getQrCode());

            Result<StoreVO> result = storeFeign.storeDetail(lottery.getStoreUserNo());
            lotteryDTO.setStoreName(result.getData().getStoreName());

            lotteryDTOS.add(lotteryDTO);
        }

        PageInfo pageInfo = new PageInfo(lotterys, navigatePages);
        pageInfo.setList(lotteryDTOS);
        return new Result<>(200, "审核通过的抽奖活动", pageInfo);
    }

    public Result<LotteryDTO> getLottery(Integer id) {
        Lottery lottery = lotteryService.getLotteryById(id);
        if (lottery == null) {
            return new Result<>(100, "此抽奖活动不存在", null);
        }
        Result<StoreVO> result = storeFeign.storeDetail(lottery.getStoreUserNo());
        QrCode qrCode = qrCodeService.getQrCodeByLotteryId(lottery.getId());
        List<Prize> prizes = prizeService.getPrizeByLotteryId(lottery.getId());

        LotteryDTO lotteryDTO = new LotteryDTO();
        BeanUtils.copyProperties(lottery, lotteryDTO);

        List<PrizeDTO> prizeDTOList = new ArrayList<>();
        for (Prize prize : prizes) {
            PrizeDTO prizeDTO = new PrizeDTO();
            BeanUtils.copyProperties(prize, prizeDTO);
            prizeDTOList.add(prizeDTO);
        }
        lotteryDTO.setStoreName(result.getData().getStoreName());
        lotteryDTO.setPrizeDTOList(prizeDTOList);
        lotteryDTO.setQrCode(qrCode.getQrCode());

        if (lottery.getAuditStatus() != 1) {
            return new Result<>(200, "此抽奖活动还未通过审核", lotteryDTO);
        }
        return new Result<>(200, "该抽奖活动具体内容", lotteryDTO);
    }

    public Result isEffectiveTIme(Integer id) {
        Lottery lottery = lotteryService.getLotteryById(id);
        if (lottery == null) {
            return new Result(100, "此抽奖活动不存在", null);
        }
        Date date = new Date();
        boolean beforeStartTime = TimeUtil.isBeforeStartTime(date, lottery.getStartTime());
        if (beforeStartTime) {
            return new Result(100, "此抽奖活动还没开始", null);
        }
        boolean afterDueTime = TimeUtil.isAfterDueTime(date, lottery.getDueTime());
        if (afterDueTime) {
            return new Result(100, "此抽奖活动已结束", null);
        }
        return new Result(200, "此抽奖活动可以参加", null);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public Result<Record> join(LotteryJoinBO lotteryJoinBO) {
        Lottery lottery = lotteryService.getLotteryById(lotteryJoinBO.getLotteryId());
        if (lottery == null) {
            return new Result<>(100, "此抽奖活动不存在", null);
        }
        if (lottery.getAuditStatus() != 1) {
            return new Result<>(100, "此抽奖活动还未通过审核", null);
        }
        //判断报名时间是否在起止时间内
        boolean isEffectiveDate = TimeUtil.isEffectiveTime(new Date(), lottery.getStartTime(), lottery.getDueTime());
        if (!isEffectiveDate) {
            return new Result<>(100, "此抽奖活动还未开始或已结束", null);
        }
        Result<UserVO> result = userFeign.userByMobile(lotteryJoinBO.getMobile());
        if (result.getData() == null) {
            return new Result<>(100, "该用户还未注册", null);
        }
        //判断用户是否已经参加，禁止重复参与同一抽奖活动
        Boolean flag = recordService.alreadyJoin(lottery.getId(), result.getData().getUserNo());
        if (!flag) {
            return new Result<>(100, "该用户已经报名了该活动，不能再重复参与同一抽奖活动", null);
        }

        Record record = new Record();
        BeanUtils.copyProperties(lotteryJoinBO, record);
        record.setUserNo(result.getData().getUserNo());
        recordService.create(record);

        //当前已参与人数+1
        stringRedisTemplate.opsForValue().increment("抽奖活动id-" + lottery.getId() + "的当前已参与人数:");

        return new Result<>(200, "报名成功", record);
    }

    public Integer numbers(Integer id) {
        Lottery lottery = lotteryService.getLotteryById(id);
        if (lottery == null) {
            return 0;
        }
        if (lottery.getAuditStatus() != 1) {
            return 0;
        }

        //从redis中查
        String key = "抽奖活动id-" + lottery.getId() + "的当前已参与人数:";
        Boolean flag = stringRedisTemplate.hasKey(key);
        if (!flag) {//不存在该key，说明已经开奖，开奖后会将这个key删掉，redis已经没有这个key
            List<Record> records = recordService.getAllWithLottery(lottery.getId());
            if (records.isEmpty()) {
                return 0;
            }
            return records.size();
        }
        return Integer.parseInt(stringRedisTemplate.opsForValue().get(key));
    }

}
